/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.openwaf.client.ui.panels;

import com.openwaf.client.core.Window;
import com.openwaf.client.dom.DivElement;
import com.openwaf.client.dom.Element;
import com.openwaf.client.dom.Node;
import com.openwaf.client.event.HandlerRegistration;
import com.openwaf.client.event.dom.MouseDownEvent;
import com.openwaf.client.event.dom.MouseDownHandler;
import com.openwaf.client.event.dom.MouseMoveEvent;
import com.openwaf.client.event.dom.MouseMoveHandler;
import com.openwaf.client.event.dom.MouseUpEvent;
import com.openwaf.client.event.dom.MouseUpHandler;
import com.openwaf.client.ui.UIControl;
import com.openwaf.client.ui.annotation.ViewElement;
import com.openwaf.client.ui.annotation.ViewMethod;
import java.util.ArrayList;

public class VerticalSplitPanel extends UIControl {


    @ViewElement
    private DivElement divContainer;
    @ViewElement
    private DivElement divTop;
    @ViewElement
    private DivElement divSplitter;
    @ViewElement
    private DivElement divBottom;

    private ArrayList topelements;
    private ArrayList bottomelements;
    private HandlerRegistration  mousemoveHandleReg;
    private HandlerRegistration  mouseupHandleReg;
    
    private int first_y;
    private int first_top_height;
    private boolean resizing;
	public VerticalSplitPanel(){				
		topelements=new ArrayList();
		bottomelements=new ArrayList();
        divSplitter.addMouseDownHandler(new MouseDownHandler() {
            public void onMouseDown(MouseDownEvent event) {
                if(resizing) return;
                onSplitterMouseDown(event);
                event.getNativeEvent().stopPropagation();
                event.getNativeEvent().preventDefault();
            }
        });		
	}
    public void setTopPanelPercentageWidth(int perc){
		if(perc<0 || perc>100){
			return;
		}
		int topheight,totheight;
		totheight=divContainer.getClientHeight()-divSplitter.getClientHeight();
		topheight=Math.round((totheight*perc)/100);
		divTop.getStyle().setHeight(""+topheight+"px");
        divSplitter.getStyle().setTop(""+divTop.getOffsetHeight()+"px");
		divBottom.getStyle().setTop(""+(divTop.getOffsetHeight()+divSplitter.getOffsetHeight())+"px");
	}

    @ViewMethod
    public void addTopElement(UIControl control){
        divTop.appendChild(control.getElement());
        topelements.add(control);
    }
    @ViewMethod
    public void addTopElement(int index,UIControl control){
        if(index<0 || index >topelements.size()){
            throw new IndexOutOfBoundsException("Index:"+index+",Size:"+topelements.size());
        }
        Node elm=divTop.getChildAt(index);
        topelements.add(index, control);
        divTop.insertBefore(control.getElement(), elm);        
    }
    public boolean removeTopElement(UIControl control){
        if(topelements.contains(control)){
            topelements.remove(control);
            divTop.removeChild(control.getElement());
            return true;
        }
        return false;
    }
    public boolean removeTopElement(int index){
        if(index<0 || index >topelements.size()){
            throw new IndexOutOfBoundsException("Index:"+index+",Size:"+topelements.size());
        }
        topelements.remove(index);
        divTop.removeChild(divTop.getChildAt(index));
        return true;
    }
    @ViewMethod
    public void addTopElement(Element element){
        divTop.appendChild(element);
        topelements.add(element);
    }
    @ViewMethod
    public void addTopElement(int index,Element element){
        if(index<0 || index >topelements.size()){
            throw new IndexOutOfBoundsException("Index:"+index+",Size:"+topelements.size());
        }
        Node elm=divTop.getChildAt(index);
        topelements.add(index, element);
        divTop.insertBefore(element, elm);
    }
    public boolean removeTopElement(Element element){
        if(topelements.contains(element)){
            topelements.remove(element);
            divTop.removeChild(element);
            return true;
        }
        return false;
    }
    //for bttom
    @ViewMethod
    public void addBottomElement(UIControl control){
        divBottom.appendChild(control.getElement());
        bottomelements.add(control);
    }
    @ViewMethod
    public void addBottomElement(int index,UIControl control){
        if(index<0 || index >bottomelements.size()){
            throw new IndexOutOfBoundsException("Index:"+index+",Size:"+topelements.size());
        }
        Node elm=divBottom.getChildAt(index);
        bottomelements.add(index, control);
        divBottom.insertBefore(control.getElement(), elm);
    }
    public boolean removeBottomElement(UIControl control){
        if(bottomelements.contains(control)){
            bottomelements.remove(control);
            divBottom.removeChild(control.getElement());
            return true;
        }
        return false;
    }
    public boolean removeBottomElement(int index){
        if(index<0 || index >bottomelements.size()){
            throw new IndexOutOfBoundsException("Index:"+index+",Size:"+bottomelements.size());
        }
        topelements.remove(index);
        divBottom.removeChild(divBottom.getChildAt(index));
        return true;
    }
    @ViewMethod
    public void addBottomElement(Element element){
        divBottom.appendChild(element);
        bottomelements.add(element);
    }
    @ViewMethod
    public void addBottomElement(int index,Element element){
        if(index<0 || index >bottomelements.size()){
            throw new IndexOutOfBoundsException("Index:"+index+",Size:"+bottomelements.size());
        }
        Node elm=divTop.getChildAt(index);
        topelements.add(index, element);
        divTop.insertBefore(element, elm);
    }
    public boolean removeBottomElement(Element element){
        if(bottomelements.contains(element)){
            bottomelements.remove(element);
            divBottom.removeChild(element);
            return true;
        }
        return false;
    }
	private void onSplitterMouseDown(MouseDownEvent e){
        resizing=true;
        first_y=e.getScreenY();
        first_top_height=divTop.getClientHeight();
        mousemoveHandleReg=Window.getDocument().addMouseMoveHandler(new MouseMoveHandler() {
            public void onMouseMove(MouseMoveEvent event) {
                event.getNativeEvent().stopPropagation();
                event.getNativeEvent().preventDefault();
                int delta=first_top_height-(first_y-event.getScreenY());
                if(delta<0) return;
                int v=divTop.getClientHeight()+divSplitter.getClientHeight()+divBottom.getClientHeight();
                v-=divSplitter.getClientHeight();
                if(delta>v) return;
                divTop.getStyle().setHeight(""+delta+"px");
                divSplitter.getStyle().setTop(""+delta+"px");
                divBottom.getStyle().setTop(""+(delta+divSplitter.getClientHeight())+"px");
                
            }
        });
        mouseupHandleReg=Window.getDocument().addMouseUpHandler(new MouseUpHandler() {
            public void onMouseUp(MouseUpEvent event) {
                mousemoveHandleReg.removeHandler();
                mouseupHandleReg.removeHandler();
                resizing=false;
            }
        });
	}
}
